<template>
    <!-- 首页根容器 -->
    <div class="home">
        <!-- 顶部统计卡片区域 -->
        <div class="statisticsBox">
            <!-- 循环渲染统计卡片 -->
            <div class="card" v-for="(item, index) in cardList" :key="item.label">
                <!-- 卡片名称 -->
                <div class="name">{{ item.label }}</div>
                <!-- Element Plus 统计组件，显示数值 -->
                <el-statistic :value="item.value" />
            </div>
        </div>
        <!-- 中部小型图表区域 -->
        <div class="minChartBox">
            <!-- 饼图容器，flex: 1 表示占据1份空间 -->
            <div style="flex: 1;" class="chart" ref="pieChartRef"></div>
            <!-- 柱状图容器，flex: 2 表示占据2份空间 -->
            <div style="flex: 2;" class="chart" ref="barChartRef"></div>
        </div>
        <!-- 底部主要图表区域 -->
        <div class="mainChartBox">
            <!-- 折线图容器 -->
            <div class="chart" ref="lineChartRef"></div>
        </div>
    </div>
</template>
<script lang="ts" setup>
// 从 vue 中导入必要的 API：ref 用于创建响应式引用，onMounted 和 onUnmounted 用于生命周期钩子，reactive 用于创建响应式对象
import { ref, onMounted, onUnmounted, reactive } from "vue"
// 导入 ECharts 主模块
import * as echarts from "echarts"
// 导入全局事件总线
import $bus from "@/bus"
// 导入 Pinia store hook
import useStore from "@/store"
// 从 vue-router 中导入 useRouter (当前未使用，但通常用于路由操作)
// import { useRouter } from "vue-router" // useRouter 在此文件中未被使用，可以移除

// 获取 Pinia store 实例
const store = useStore()

// 定义统计卡片的响应式数据列表
const cardList = reactive([{
    label: "销售额", // 卡片标签
    value: 484616  // 卡片数值
}, {
    label: "库存数",
    value: 88888
}, {
    label: "成交量",
    value: 5123
}, {
    label: "订单数",
    value: 6541
}])

// 组件挂载后执行的钩子
onMounted(() => {
    // 渲染所有图表
    renderAllChart()
})

// 组件卸载前执行的钩子
onUnmounted(() => {
    // 遍历并断开所有图表的 ResizeObserver 实例，防止内存泄漏
    chartObsMap.forEach(item => {
        item.disconnect()
    })
    // 移除事件总线上关于主题和主颜色变化的监听器
    $bus.off(["themeChange", "primaryColorChange"], renderAllChart)
})
// 监听全局事件总线上的主题变化和主颜色变化事件，当事件触发时重新渲染所有图表
$bus.on(["themeChange", "primaryColorChange"], renderAllChart)

// 用于存储图表 ResizeObserver 实例的 Map 对象，键为图表标识，值为 ResizeObserver 实例
const chartObsMap = new Map<string, ResizeObserver>()

// 饼图相关的 ref 和渲染函数
const pieChartRef = ref() // 获取饼图 DOM 元素的引用
// 渲染饼图的函数
function renderPieChart() {
    // 初始化 ECharts 实例，关联到 pieChartRef.value (即饼图的 DOM 元素)
    const pieChart = echarts.init(pieChartRef.value)
    // 饼图的配置项
    const option = {
        tooltip: { // 提示框组件
            trigger: 'item', // 触发类型：数据项图形触发
        },
        series: [ // 系列列表
            {
                name: 'Access From', // 系列名称，用于 tooltip 的显示
                type: 'pie', // 图表类型：饼图
                radius: ['40%', '70%'], // 饼图的半径，内半径为40%，外半径为70%，形成环形图
                avoidLabelOverlap: false, // 是否启用防止标签重叠策略
                padAngle: 5, // 扇区之间的间隔角度
                itemStyle: { // 图形样式
                    borderRadius: 10 // 扇区的圆角
                },
                label: { // 饼图图形上的文本标签
                    show: false, // 不显示标签
                    position: 'center' // 标签位置（此处不显示，所以此配置无效）
                },
                emphasis: { // 高亮状态下的样式
                    label: {
                        show: true, // 高亮时显示标签
                        fontSize: 14, // 标签字号
                        fontWeight: 'bold', // 标签字重
                        // 标签颜色，从 CSS 变量中获取，确保与主题一致
                        color: window.getComputedStyle(document.documentElement).color
                    }
                },
                labelLine: { // 标签的视觉引导线样式
                    show: false // 不显示引导线
                },
                data: [ // 系列数据
                    { value: 1048, name: 'Search Engine' },
                    { value: 735, name: 'Direct' },
                    { value: 580, name: 'Email' },
                    { value: 484, name: 'Union Ads' },
                    { value: 300, name: 'Video Ads' }
                ]
            }
        ]
    };
    // 应用配置项到图表实例
    pieChart.setOption(option)

    // 监听图表容器尺寸变化，实现图表自适应
    // 如果 chartObsMap 中还没有该图表的 ResizeObserver 实例
    if (!chartObsMap.has("pieChart")) {
        // 创建一个新的 ResizeObserver 实例
        const obs = new ResizeObserver(() => {
            // 当容器尺寸变化时，调用 ECharts 实例的 resize 方法调整图表大小
            pieChart.resize()
        })
        // 开始观察 pieChartRef.value (饼图 DOM 元素) 的尺寸变化
        obs.observe(pieChartRef.value)
        // 将 ResizeObserver 实例存入 chartObsMap
        chartObsMap.set("pieChart", obs)
    }
}

// 柱状图相关的 ref 和渲染函数
const barChartRef = ref() // 获取柱状图 DOM 元素的引用
// 渲染柱状图的函数
function renderBarChart() {
    // 初始化 ECharts 实例
    const barChart = echarts.init(barChartRef.value)
    // 柱状图的配置项
    const option = {
        tooltip: { // 提示框组件
            trigger: "axis" // 触发类型：坐标轴触发
        },
        grid: { // 直角坐标系内绘图网格
            bottom: "10%", // grid 组件离容器下侧的距离
            right: "5%",   // grid 组件离容器右侧的距离
            left: "8%"     // grid 组件离容器左侧的距离
        },
        xAxis: { // x 轴配置
            type: 'category', // 类型：类目轴
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], // 类目数据
            axisLabel: { // 坐标轴刻度标签的相关设置
                // 刻度标签颜色，从 CSS 变量中获取
                color: window.getComputedStyle(document.documentElement).color
            },
        },
        yAxis: { // y 轴配置
            type: 'value', // 类型：数值轴
            axisLabel: { // 坐标轴刻度标签的相关设置
                // 刻度标签颜色，从 CSS 变量中获取
                color: window.getComputedStyle(document.documentElement).color
            },
            splitLine: { // 分隔线相关设置
                lineStyle: {
                    // 分隔线颜色，根据当前主题（暗黑/明亮）设置
                    color: store.isDarkTheme ? "#333" : "#ddd"
                }
            },
        },
        series: [ // 系列列表
            {
                data: [120, 200, 150, 80, 70, 110, 130], // 系列数据
                type: 'bar', // 图表类型：柱状图
                itemStyle: { // 图形样式
                    color: { // 柱条颜色使用线性渐变
                        type: 'linear', // 渐变类型
                        x: 0, y: 0, x2: 0, y2: 1, // 渐变方向 (从上到下)
                        colorStops: [ // 渐变颜色点
                            { offset: 0, color: store.primaryColor }, // 起始颜色：主题主色
                            // 结束颜色：图表容器的背景色，实现渐变到底部透明的效果
                            { offset: 1, color: window.getComputedStyle(barChartRef.value).backgroundColor }
                        ]
                    }
                }
            }
        ]
    };
    // 应用配置项
    barChart.setOption(option)

    // 监听图表容器尺寸变化，实现图表自适应
    if (!chartObsMap.has("barChart")) {
        const obs = new ResizeObserver(() => {
            barChart.resize()
        })
        obs.observe(barChartRef.value)
        chartObsMap.set("barChart", obs)
    }
}


// 折线图相关的 ref 和渲染函数
const lineChartRef = ref() // 获取折线图 DOM 元素的引用
// 渲染折线图的函数
function renderLineChart() {
    // 初始化 ECharts 实例
    const lineChart = echarts.init(lineChartRef.value)
    // 折线图的配置项
    const option = {
        tooltip: { // 提示框组件
            trigger: "axis" // 坐标轴触发
        },
        grid: { // 网格配置
            left: "5%",
            right: "5%",
            bottom: "10%"
        },
        xAxis: { // x 轴配置
            type: 'category', // 类目轴
            boundaryGap: false, // 类目轴中 boundaryGap 是否保留类目轴两端的空白策略
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], // 类目数据
            axisLabel: { // 刻度标签颜色
                color: window.getComputedStyle(document.documentElement).color
            },
        },
        yAxis: { // y 轴配置
            type: 'value', // 数值轴
            splitLine: { // 分割线样式
                lineStyle: {
                    color: store.isDarkTheme ? "#333" : "#ddd" // 根据主题设置颜色
                }
            },
            axisLabel: { // 刻度标签颜色
                color: window.getComputedStyle(document.documentElement).color
            }
        },
        series: [ // 系列列表
            {
                data: [820, 932, 901, 934, 1290, 1330, 1320], // 系列数据
                type: 'line', // 图表类型：折线图
                lineStyle: { // 折线样式
                    color: store.primaryColor // 折线颜色使用主题主色
                },
                itemStyle: { // 数据项图形的样式 (拐点)
                    color: store.primaryColor // 拐点颜色使用主题主色
                },
                areaStyle: { // 区域填充样式
                    opacity: 1, // 透明度
                    color: { // 填充颜色使用线性渐变
                        type: 'linear',
                        x: 0, y: 0, x2: 0, y2: 1, // 从上到下渐变
                        colorStops: [
                            { offset: 0, color: store.primaryColor }, // 起始颜色：主题主色
                            // 结束颜色：图表容器的背景色 (注意: 此处 barChartRef.value 可能不是期望的，应为 lineChartRef.value 或更通用的背景色获取方式)
                            // 建议修改为: { offset: 1, color: window.getComputedStyle(lineChartRef.value).backgroundColor }
                            // 或者一个固定的透明色: { offset: 1, color: 'rgba(0,0,0,0)' } 如果背景色不确定
                            { offset: 1, color: window.getComputedStyle(lineChartRef.value).backgroundColor } // 已修正为 lineChartRef
                        ]
                    }
                },
                smooth: true // 是否平滑曲线显示
            }
        ]
    };
    // 应用配置项
    lineChart.setOption(option)

    // 监听图表容器尺寸变化，实现图表自适应
    if (!chartObsMap.has("lineChart")) {
        const obs = new ResizeObserver(() => {
            lineChart.resize()
        })
        obs.observe(lineChartRef.value)
        chartObsMap.set("lineChart", obs)
    }
}

// 统一渲染所有图表的函数
function renderAllChart() {
    renderPieChart()
    renderBarChart()
    renderLineChart()
}

</script>
<style lang="scss" scoped>
// 首页根容器样式
.home {
    display: flex; // 使用 flex 布局
    flex-direction: column; // 子元素垂直排列
    gap: 10px; // 子元素之间的间距
    height: 100%; // 高度占满父容器
    overflow: auto; // 内容超出时显示滚动条

    // 顶部统计卡片区域样式
    .statisticsBox {
        width: 100%; // 宽度占满父容器
        display: flex; // 使用 flex 布局
        gap: 20px; // 卡片之间的间距

        // 单个统计卡片样式
        .card {
            flex: 1 0; // flex 布局：可伸缩，初始大小不固定，基准大小为0 (等分剩余空间)
            text-align: center; // 文本居中
            padding: 10px; // 内边距
            border-radius: 4px; // 圆角
            display: flex; // 使用 flex 布局
            flex-direction: column; // 卡片内元素垂直排列
            gap: 8px; // 卡片内元素间距
            background-color: var(--box-bg-color); // 背景色使用 CSS 变量
            box-shadow: var(--box-shadow); // 阴影使用 CSS 变量
        }
    }

    // 中部小型图表区域样式
    .minChartBox {
        width: 100%; // 宽度占满
        display: flex; // flex 布局
        gap: 20px; // 图表间距
        height: 260px; // 固定高度
        flex-shrink: 0; // flex 布局：不收缩，保持固定高度
        overflow: hidden; // 超出部分隐藏，确保图表在容器内

        // 单个图表容器样式
        .chart {
            flex: 1; // flex 布局：等分空间
            border-radius: 4px; // 圆角
            background-color: var(--box-bg-color); // 背景色
            box-shadow: var(--box-shadow); // 阴影
            overflow: hidden; // 超出部分隐藏
        }
    }

    // 底部主要图表区域样式
    .mainChartBox {
        width: 100%; // 宽度占满
        flex: 1; // flex 布局：占据剩余所有垂直空间

        // 图表容器样式
        .chart {
            width: 100%; // 宽度占满
            height: 100%; // 高度占满
            border-radius: 4px; // 圆角
            background-color: var(--box-bg-color); // 背景色
            box-shadow: var(--box-shadow); // 阴影
            overflow: hidden; // 超出部分隐藏
        }
    }
}
</style>